package com.testDemo.hutool;

import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.HexUtil;
import cn.hutool.crypto.Mode;
import cn.hutool.crypto.Padding;
import cn.hutool.crypto.SmUtil;
import cn.hutool.crypto.symmetric.SM4;
import cn.hutool.crypto.symmetric.SymmetricCrypto;
import org.bouncycastle.pqc.math.linearalgebra.ByteUtils;
import org.junit.jupiter.api.Test;

import javax.crypto.SecretKey;

import java.nio.charset.StandardCharsets;

import static cn.hutool.crypto.Mode.ECB;
import static cn.hutool.crypto.Padding.PKCS5Padding;

/**
 * @author: zouren
 * @date: 2022/2/17
 * @description:
 */
public class SmUtilTest {
    public static final String ALGORITHM_NAME_ECB_PADDING = "SM4/ECB/PKCS5Padding";
    public static final String ALGORITHM_NAME_ECB_NOPADDING = "SM4/ECB/NoPadding";
    public static final String ALGORITHM_NAME_CBC_PADDING = "SM4/CBC/PKCS5Padding";
    public static final String ALGORITHM_NAME_CBC_NOPADDING = "SM4/CBC/NoPadding";

    @Test
    public void sm4(){
        String content = "{\"psnName\":\"张三\",\"psnCertType\":\"01\",\"certNo\":\"140101199909091100\"}";
        String key = "OBNSCI5GBL0QJ2947R0CSS4TB4787E77".substring(0,16);
        SymmetricCrypto sm4 =  new SM4( ECB, PKCS5Padding, key.getBytes(CharsetUtil.CHARSET_UTF_8));
        String encryptHex = sm4.encryptHex(content);
        System.out.println("ECB加密后的数据：" +encryptHex);
        String decryptStr = sm4.decryptStr(encryptHex, CharsetUtil.CHARSET_UTF_8);
        System.out.println("ECB解密后的数据：" +decryptStr);
        System.out.println("================================");
        encryptHex = "15402A7FA27009F263DAEE939B58C2BFD9606AE13850E491EE8E697BBB1B523B5527584E16386051B594B5922329E6C9505C7B8D0AD38A3D1DDFB000DB25D50D185A68E1EA884F30E61C8587F8B3ABF8780D45134CBE017AF64A01213843AC7A";
        decryptStr = sm4.decryptStr(encryptHex, CharsetUtil.CHARSET_UTF_8);
        System.out.println("ECB解密后的数据：" +decryptStr);
        System.out.println(encryptHex);
    }

    @Test
    public void testCustomKeySM4ECB() throws Exception {
        String charset = StandardCharsets.UTF_8.name();
        // SM4密钥长度分组长度128bit，因此密匙长度为16
        String myKey = "OBNSCI5GBL0QJ2947R0CSS4TB4787E77".substring(0,16);
        String data = "{\"psnName\":\"张三\",\"psnCertType\":\"01\",\"certNo\":\"140101199909091100\"}";
        byte[] myKeyBytes = myKey.getBytes(charset);
        byte[] encryptedBytes = SM4Utils.encrypt_ECB_Padding(myKeyBytes, data.getBytes(charset));
        String encryptedHexString = ByteUtils.toHexString(encryptedBytes);

        SymmetricCrypto sm4 =  new SM4( ECB, PKCS5Padding,myKeyBytes);
        String encryptHex = sm4.encryptHex(data);
        System.out.println(encryptHex);
        System.out.println("ECB加密后的数据HexString1：" + encryptedHexString);
        System.out.println("ECB加密后的数据HexString2：" + encryptHex);
        byte[] decryptedBytes = SM4Utils.decrypt_ECB_Padding(myKeyBytes, ByteUtils.fromHexString(encryptedHexString));
        String decryptStr = sm4.decryptStr(encryptHex, CharsetUtil.CHARSET_UTF_8);
        System.out.println("ECB解密后的数据1：" + new String(decryptedBytes, charset));
        System.out.println("ECB解密后的数据2：" + decryptStr);
    }

    @Test
    public void testCustomKeySM4CBC() throws Exception {
        String charset = StandardCharsets.UTF_8.name();
        // SM4密钥长度分组长度128bit，因此密匙长度为16
        String myKey = "1234567812345678";
        String myIv = "8765432187654321";
        String data = "SM4UtilsTest";
        byte[] myKeyBytes = myKey.getBytes(charset);
        byte[] myIvBytes = myIv.getBytes(charset);
        byte[] encryptedBytes = SM4Utils.encrypt_CBC_Padding(myKeyBytes, myIvBytes, data.getBytes(charset));
        String encryptedHexString = ByteUtils.toHexString(encryptedBytes);
        System.out.println("CBC加密后的数据HexString：" + encryptedHexString);
        byte[] decryptedBytes = SM4Utils.decrypt_CBC_Padding(myKeyBytes, myIvBytes, ByteUtils.fromHexString(encryptedHexString));
        System.out.println("CBC解密后的数据：" + new String(decryptedBytes, charset));
    }

}
